package pfq.demo.reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * Created by pangfuqiang on 2018/2/22.
 */

public class Main {

    public static void main(String[] args) {

        Person person = new Person("pangfuqiang", 27);

        // 得到Class对象的三种方式
        Class clz1 = null;
        try {
            clz1 = Class.forName("pfq.demo.reflect.Person");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        Class clz2 = Person.class;

        Class clz3 = person.getClass();

        System.out.println(clz1 == clz2);
        System.out.println(clz1 == clz3);
        System.out.println(clz2 == clz3);

        testConstructor(clz1);

        testField(clz1, person);

        testMethod(clz1, person);

        pfq.demo.kotlin.lesson2.Person p = new pfq.demo.kotlin.lesson2.Person();

    }

    /**
     * 通过反射调用构造函数进行实例化
     */
    public static void testConstructor(Class clz) {
        try {
            Constructor constructor = clz.getConstructor(String.class, int.class);
            try {
                Person person = (Person) constructor.newInstance("pangfuqiang", 27);
                System.out.println("姓名：" + person.getName());
                System.out.println("年龄：" + person.getAge());

            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }

    }

    public static void testField(Class clz, Person person) {

        Field[] fields = clz.getFields();

        System.out.println("不包括私有变量：");
        for (int i = 0; i < fields.length; i++) {
            System.out.println(fields[i]);
        }

        Field[] declaredFields = clz.getDeclaredFields();

        System.out.println("包括私有变量：");
        for (int i = 0; i < declaredFields.length; i++) {
            System.out.println(declaredFields[i]);
        }

        try {
            declaredFields[0].setAccessible(true);
            System.out.println(declaredFields[0].getName() + ": " + declaredFields[0].get(person));
            declaredFields[0].set(person, "庞富强");
            System.out.println(declaredFields[0].getName() + ": " + declaredFields[0].get(person));
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    public static void testMethod(Class clz, Person person) {

        try {
            Method method = clz.getMethod("getName");
            System.out.println(method.invoke(person, (Object) null));
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

    }

}
